package com.guigu.pd.oms.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guigu.common.utils.PageVo;
import com.guigu.common.utils.R;
import com.guigu.pd.oms.common.CustomIdGenerator;
import com.guigu.pd.oms.entity.*;
import com.guigu.pd.oms.service.OrderCargoService;
import com.guigu.pd.serviceapi.authfeign.CoreOrgFeign;
import com.guigu.pd.serviceapi.authfeign.SsqFeign;
import com.guigu.pd.serviceapi.basefeign.GoodsTypeFeign;
import com.guigu.pd.serviceapi.omsfeign.OrderCargoFeign;
import com.guigu.pd.serviceapi.pojo.OrderCargoEntity;
import com.guigu.pd.serviceapi.pojo.OrderEntity;
import com.guigu.pd.serviceapi.pojo.TaskPickupDispatch;
import com.guigu.pd.oms.service.OrderLocationService;
import com.guigu.pd.oms.utils.BaiduMapUtils;
import com.guigu.pd.serviceapi.authfeign.UserFeign;
import com.guigu.pd.serviceapi.pojo.TaskPickupDispatchEntity;
import com.guigu.pd.serviceapi.workfeign.TaskPickupDispatchFeign;
import com.guigu.pd.serviceapi.workfeign.TransportOrderFeign;
import org.apache.commons.lang.StringUtils;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.common.utils.PageUtils;
import com.guigu.common.utils.Query;

import com.guigu.pd.oms.dao.OrderDao;
import com.guigu.pd.oms.service.OrderService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {


    @Autowired
    private CustomIdGenerator customIdGenerator;

    @Autowired
    private OrderLocationService orderLocationService;


    @Resource
    private UserFeign userFeign;

    @Resource
    private TaskPickupDispatchFeign taskPickupDispatchFeign;

    @Autowired
    private OrderCargoService orderCargoService;

    @Autowired
    TransportOrderFeign transportOrderFeign;

    @Autowired
    SsqFeign ssqFeign;

    @Autowired
    CoreOrgFeign coreOrgFeign;

    @Autowired
    OrderCargoFeign orderCargoFeign;

    @Autowired
    private GoodsTypeFeign goodsTypeFeign;

    //注入

    @Override
    public PageVo<OrderEntity> queryPage(Map<String, Object> params) {
        OrderEntity
                orderinfo = JSON.parseObject(JSON.toJSONString(params),
                OrderEntity.class);

        Integer pageno = Integer.parseInt(params.get("pageno").toString());
        Integer pagesize = Integer.parseInt(params.get("pagesize").toString());

        LambdaQueryWrapper<OrderEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(orderinfo.getId()),
                OrderEntity::getId, orderinfo.getId());

        queryWrapper.like(orderinfo.getStatus()!=null && orderinfo.getStatus()!=0,
                OrderEntity::getStatus, orderinfo.getStatus());

        queryWrapper.like(orderinfo.getPaymentStatus()!=null,
                OrderEntity::getPaymentStatus, orderinfo.getPaymentStatus());

        queryWrapper.like(StringUtils.isNotBlank(orderinfo.getSenderName()),
                OrderEntity::getSenderName, orderinfo.getSenderName());

        queryWrapper.like(orderinfo.getSenderPhone()!=null,
                OrderEntity::getSenderPhone, orderinfo.getSenderPhone());

        if (StringUtils.isNotBlank(orderinfo.getSenderAddress()) && !orderinfo.getSenderAddress().equals(",,")) {
            String senderaddress = orderinfo.getSenderAddress();
            String[] split = senderaddress.split(",");
            Integer shenid = Integer.valueOf(split[0]);
            Integer shiid = Integer.valueOf(split[1]);
            Integer quid = Integer.valueOf(split[2]);
            String shen = ssqFeign.getnamebyId(shenid);
            String shi = ssqFeign.getnamebyId(shiid);
            String qu = ssqFeign.getnamebyId(quid);
            String address = shen + shi + qu;
            queryWrapper.like(StringUtils.isNotBlank(orderinfo.getSenderAddress()) && !orderinfo.getSenderAddress().equals(",,"),
                    OrderEntity::getSenderAddress, address);
        }

        queryWrapper.like(StringUtils.isNotBlank(orderinfo.getReceiverName()),
                OrderEntity::getReceiverName, orderinfo.getReceiverName());

        queryWrapper.like(orderinfo.getReceiverPhone()!=null,
                OrderEntity::getReceiverPhone, orderinfo.getReceiverPhone());

        if (StringUtils.isNotBlank(orderinfo.getReceiverAddress()) && !orderinfo.getSenderAddress().equals(",,")) {
            String receiveaddress = orderinfo.getReceiverAddress();
            String[] split = receiveaddress.split(",");
            Integer shenid = Integer.valueOf(split[0]);
            Integer shiid = Integer.valueOf(split[1]);
            Integer quid = Integer.valueOf(split[2]);
            String shen = ssqFeign.getnamebyId(shenid);
            String shi = ssqFeign.getnamebyId(shiid);
            String qu = ssqFeign.getnamebyId(quid);
            String address = shen + shi + qu;
            queryWrapper.like(StringUtils.isNotBlank(orderinfo.getReceiverAddress()) && !orderinfo.getSenderAddress().equals(",,"),
                    OrderEntity::getReceiverAddress, address);
        }

        PageHelper.startPage(pageno, pagesize);
        List<OrderEntity> orders = this.list(queryWrapper);

        for (OrderEntity order : orders) {
            //运单id查询    获取运单编号
            String transportOrderId = transportOrderFeign.getTransportbyorderId(order.getId());
            order.setTransportorderid(transportOrderId);
        }
        PageInfo<OrderEntity> pageInfo = new PageInfo<OrderEntity>(orders);

        PageVo<OrderEntity> pageVo = new PageVo<OrderEntity>();
        pageVo.setRows(pageInfo.getList());
        pageVo.setTotal(pageInfo.getTotal());

        return pageVo;
    }


    //下单
    @Override
    public R kuhuxiadanjijian(Map<String, Object> params) {

        OrderEntity orderEntity = JSON.parseObject(JSON.toJSONString(params),OrderEntity.class);
        //首先生成订单id
        String orderId = customIdGenerator.nextId(orderEntity)+"";

        orderEntity.setId(orderId);
        //下单时间
        orderEntity.setCreateTime(new Date());
        //默认订单状态为 1未分配
        orderEntity.setStatus(1);
        String gtid = goodsTypeFeign.getgoodstypebyId(orderEntity.getGoodsTypeId());
        orderEntity.setGoodsTypeName(gtid);

        //默认订单为城际订单
        orderEntity.setOrderType(2);
        //获取发件地和收件地址的市编号是否相等
        String receiverCityId = orderEntity.getReceiverCityId();

        String senderCityId = orderEntity.getSenderCityId();

        if(receiverCityId==senderCityId){
            orderEntity.setOrderType(1);
        }


        //输入寄件人信息
        //输入收件人信息
        //选填取件类型，1为网点自寄，2为上门取件
        //选填货物类别

        //获取到寄件人的地理坐标
        //拼接寄件人地址     112.902077,28.128111
        // " 湖南省长沙市岳麓区学士街道339号";
        String sprovincename = ssqFeign.getnamebyId(Integer.parseInt(orderEntity.getSenderProvinceId()));
        String scityname = ssqFeign.getnamebyId(Integer.parseInt(orderEntity.getSenderCityId()));
        String scountryname = ssqFeign.getnamebyId(Integer.parseInt(orderEntity.getSenderCountyId()));
        orderEntity.setSenderProvinceName(sprovincename);
        orderEntity.setSenderCityName(scityname);
        orderEntity.setSenderCountyName(scountryname);
        orderEntity.setSenderAddress(sprovincename+scityname+scountryname+orderEntity.getSenderAddress());
        String senderAddr = sprovincename+scityname+scountryname+orderEntity.getSenderAddress();

        //拼接收件人地址     北京市海淀区中成大厦    116.317174,39.992144
       //"北京市海淀区中成大厦";
        String rprovincename = ssqFeign.getnamebyId(Integer.parseInt(orderEntity.getReceiverProvinceId()));
        String rcityname = ssqFeign.getnamebyId(Integer.parseInt(orderEntity.getReceiverCityId()));
        String rcountryname = ssqFeign.getnamebyId(Integer.parseInt(orderEntity.getReceiverCountyId()));
        orderEntity.setReceiverProvinceName(rprovincename);
        orderEntity.setReceiverCityName(rcityname);
        orderEntity.setReceiverCountyName(rcountryname);
        orderEntity.setReceiverAddress(rprovincename+rcityname+rcountryname+orderEntity.getReceiverAddress());
        String receiverAddr =  rprovincename+rcityname+rcountryname+orderEntity.getReceiverAddress();


        //将发收货地址转换成坐标
        String sendercoordinate = BaiduMapUtils.getCoordinate(senderAddr);
        String receivercoordinate = BaiduMapUtils.getCoordinate(receiverAddr);

        if(sendercoordinate==""||receivercoordinate==""){
            return R.ok("请输入正确的地址");
        }


        //TODO 计算发收货地址所属网点id
        //TODO 根据该发货点的位置获取到他所在区县id
        //TODO 根据区县id找到它下属所有网点判断发货点坐标在哪一快递网点范围类
        //根据发件人的发货位置（快递员的收件位置）经纬度
        //学士街道网点
//        String senderwangdian = "901";
        //所属发货网点id
        //根据发件人区县id 去组织表找到对应的曲线下面的网点坐标（组织级别为4）  得到距离 订单所属网点为最近网点id
        String senderCountyId = orderEntity.getSenderCountyId();
        String senderwangdian = coreOrgFeign.chazhaofhid(sendercoordinate, senderCountyId);

        if(senderwangdian.equals("qqq")){
            return  R.ok("该地区没有网点，请添加网点");
        }


        //收货网点id
        //北京海淀区北京大学网点
        //        String receiverwangdian = "1067246875800000001";

        String receiverCountyId = orderEntity.getReceiverCountyId();
        String receiverwangdian =  coreOrgFeign.chazhaofhid(receivercoordinate, receiverCountyId);
                //"58000";

        if(receiverwangdian.equals("qqq")){
            return  R.ok("该地区没有网点，请添加网点");
        }


        //给订单表设置订单当前所属网点
        orderEntity.setCurrentAgencyId(senderwangdian);

        //设置发收货距离
        Double distance = BaiduMapUtils.getDistance(sendercoordinate, receivercoordinate);
        DecimalFormat df = new DecimalFormat("#.##");
        String distanceStr = df.format(distance / 1000);
        BigDecimal orderDistance = new BigDecimal(distanceStr);
        orderEntity.setDistance(orderDistance);

        ////计算订单价格（距离加重量）
        String s = this.calculateAmount(orderDistance, orderEntity.getTotalWeight());
        orderEntity.setAmount(new BigDecimal(s));


        //添加`pd_order_location`收发货的坐标详情
        com.guigu.pd.serviceapi.pojo.OrderLocationEntity orderLocationEntity = new com.guigu.pd.serviceapi.pojo.OrderLocationEntity();
        orderLocationEntity.setId(customIdGenerator.nextId(orderLocationEntity)+"");
        orderLocationEntity.setOrderId(orderId);
        orderLocationEntity.setSendLocation(sendercoordinate);
        orderLocationEntity.setReceiveLocation(receivercoordinate);
        //TODO 添加发收货网点编号
        orderLocationEntity.setSendAgentId(senderwangdian);
        orderLocationEntity.setReceiveAgentId(receiverwangdian);
        //添加
        orderLocationService.save(orderLocationEntity);


        //pd_order_cargo 货物信息表数据
        OrderCargoEntity orderCargoEntity = new OrderCargoEntity();
        orderCargoEntity.setId(customIdGenerator.nextId(orderCargoEntity)+"");
        orderCargoEntity.setOrderId(orderId);
        orderCargoEntity.setGoodsTypeId(orderEntity.getGoodsTypeId());
        orderCargoEntity.setName(orderEntity.getGoodsName());
        orderCargoEntity.setTotalWeight(orderEntity.getTotalWeight());
        orderCargoService.save(orderCargoEntity);


        TaskPickupDispatch taskPickupDispatchEntity = new TaskPickupDispatch();

        //关联订单id
        taskPickupDispatchEntity.setOrderId(orderId);

        //任务类型，1为取件任务，2为派件任务 0为网点自寄
        //先默认为0 客户网点自寄
        taskPickupDispatchEntity.setTaskType(0);

        //所属网点id
        taskPickupDispatchEntity.setAgencyId(senderwangdian);

        //首先快递员收件状态默认为
        //任务状态，1为待执行（对应 待上门和须交接）、2为进行中（该状态暂不使用，属于保留状态）、3为待确认（对应 待妥投和须交件）、4为已完成、5为已取消
        taskPickupDispatchEntity.setStatus(1);

        //设置网点id
        taskPickupDispatchEntity.setAgencyId(senderwangdian);


        //判断 1为网点自寄，2为上门取件
        //为网点自寄 不需要安排快递员上门
        if (orderEntity.getPickupType()==2) {
            //为上门取件 根据订单所属网点安排空闲快递员上门取件
            //生成快递员作业单

           //上门取件就要将任务状态改成取件任务 替换默认的  0为网点自寄
            taskPickupDispatchEntity.setTaskType(1);

          //首先将任务分配状态(1未分配2已分配3待人工分配 0自行寄件《默认》) 标识未分配
            taskPickupDispatchEntity.setAssignedStatus(1);


            //获取该网点的快递员id
            String getuserkdy = userFeign.getuserkdy(senderwangdian);
            String[] str = getuserkdy.split(",");
            //用来存储快递员的未完成的收货订单数量

            //循环查出 //获取该网点的随机一个快递员进行收件(根据快递员编号和快递员作业表 status列判断是否为 2 进行中 小于5)
            int panduanshoujiankdy = taskPickupDispatchFeign.panduanshoujiankdy(getuserkdy);


            if(panduanshoujiankdy!=-1){
                //添加快递员id
                taskPickupDispatchEntity.setCourierId(str[panduanshoujiankdy]);
                taskPickupDispatchEntity.setEstimatedStartTime(new Date());
                taskPickupDispatchEntity.setActualStartTime(new Date());
                //TODO 这里要做成定时任务 如果网点有需要取件的任务则每10分钟寻找空闲快递员去取件
                //上门取件必须要有空闲快递员时才能修改取件任务状态 2为进行中（该状态暂不使用，属于保留状态）
                taskPickupDispatchEntity.setStatus(2);

                //有空闲快递员将任务分配状态(1未分配2已分配3待人工分配 0自行寄件《默认》) 标识已分配
                taskPickupDispatchEntity.setAssignedStatus(2);

                //有快递员去取件 订单状态为 2已分配(代取件)
                orderEntity.setStatus(2);
            }
        }
            //添加快递员收货订单
        boolean savekdylanjian = taskPickupDispatchFeign.savekdylanjian(taskPickupDispatchEntity);


        boolean save = this.save(orderEntity);

        if(save){
            return R.ok("添加成功");
        }
        return R.ok("添加失败");
    }



    @Override
    @Transactional
    public String calculateAmount(BigDecimal distance, BigDecimal totalWeight) {

        KieSession session = ReloadDroolsRulesService.kieContainer.newKieSession();


        //设置Fact对象
        AddressRule addressRule = new AddressRule();
        addressRule.setTotalWeight(totalWeight.doubleValue());
        addressRule.setDistance(distance.doubleValue());

        //将对象加入到工作内存
        session.insert(addressRule);

        AddressCheckResult addressCheckResult = new AddressCheckResult();
        session.insert(addressCheckResult);

        int i = session.fireAllRules();
        System.out.println("触发了" + i + "条规则");
        session.destroy();

        if(addressCheckResult.isPostCodeResult()){
            System.out.println("规则匹配成功,订单价格为：" + addressCheckResult.getResult());


               return addressCheckResult.getResult();

        }

        return null;
    }


    @Override
    public OrderEntity getorderbyId(String id) {
        OrderEntity order = this.getById(id);

        String transportbyorderId = transportOrderFeign.getTransportbyorderId(id);
        order.setTransportorderid(transportbyorderId);

        List<OrderCargoEntity> ordercargolist = new ArrayList<OrderCargoEntity>();
        OrderCargoEntity orderCargo = orderCargoFeign.getordercargobyId(id);
        ordercargolist.add(orderCargo);
        order.setOrdercargo(ordercargolist);

        TaskPickupDispatchEntity pickupDispatch = taskPickupDispatchFeign.getbyorderId(id);
        String agencyname = coreOrgFeign.getcornamebyid(pickupDispatch.getAgencyId());
        String userstr = userFeign.getuserbyId(pickupDispatch.getCourierId());
        String[] split = userstr.split(",");
        if(split.length==2){
            pickupDispatch.setCourier(split[0]);
            pickupDispatch.setCphone(split[1]);
        }
        if (split.length==1){
            pickupDispatch.setCourier(split[0]);
        }
        pickupDispatch.setAgencyname(agencyname);
        order.setTaskpt(pickupDispatch);
        return order;
    }

}